package com.storage.view.widgets.grid
{
	import com.storage.util.LoadXmlUtil;
	import com.storage.view.widgets.form.NumberField;
	import com.storage.view.widgets.form.RadioHBox;
	import com.storage.view.widgets.form.ZZComBox;
	import com.storage.view.widgets.form.ZZEditForm;
	import com.storage.view.widgets.itemRenderer.DateRenderer;
	import com.storage.view.widgets.itemRenderer.EntityRenderer;
	import com.storage.vo.query.FieldVO;
	import com.storage.vo.query.QueryInfoVO;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.Dictionary;
	
	import flexlib.containers.FlowBox;
	
	import mx.collections.ArrayCollection;
	import mx.containers.FormItem;
	import mx.containers.HBox;
	import mx.containers.VBox;
	import mx.controls.Button;
	import mx.controls.CheckBox;
	import mx.controls.ComboBox;
	import mx.controls.DataGrid;
	import mx.controls.DateField;
	import mx.controls.Label;
	import mx.controls.RadioButton;
	import mx.controls.Spacer;
	import mx.controls.TextArea;
	import mx.controls.TextInput;
	import mx.controls.dataGridClasses.DataGridColumn;
	import mx.core.ClassFactory;
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
	import mx.rpc.events.ResultEvent;


	[Event(name="search",type="mx.events.Event")]	//查询事件
	[Event(name="change", type="mx.events.Event")]	//变化事件
	[Event(name="sendBindObject", type="mx.events.Event")]	//变化事件
	[Event(name="delete", type="mx.events.Event")]	//变化事件
	public class ZZGrid extends VBox
	{
		
		
//		[Bindable]
//		public var dateGridList:ArrayCollection = new ArrayCollection() ;
		
		//data grid
		private var _dataGrid:DataGrid;
		//data grid's column set
		private var _columns:Array;
		//data grid's config xml list data
		private var _xmlData:Array = new Array();
		//button hbox
		private var _btnBox:HBox;
		// add button
		private var _addBtn:Button;
		//delete button
		private var _delBtn:Button;
		//update button
		private var _updateBtn:Button;
		//xml url
		private var _url:String;
		//form xml data
		private var _formData:Array = new Array();
		//the flowbox's container
		private var _formBox:VBox;
		//form items container
		private var _formFlowBox:FlowBox;
		private var _searchButton:Button;
		private var _resetButtion:Button;
		private var _searchBBox:HBox;
		
		private var _readOnly:Boolean;
		
		//-----------------//----------------//
		public var doSearchHandler:Function;
		public var sendBindObject:Function;
		public var deleteObject:Function;
		public var addObject:Function;
		public var resetHanlder:Function;
		//-----------------//----------------//
		
		private var _comboxList:ArrayCollection = new ArrayCollection;
		[Bindable]
		private var _comboBoxDataDic:Dictionary = new Dictionary();
		private var _controlDic:Dictionary = new Dictionary();
		private var _controlList:ArrayCollection = new ArrayCollection();
		
		public var FLOWBOXHEIGHT:Number = 25;	
		public var LABWIDTH:Number = 95;
		public var HORGAP:Number = 15;
		public var CONTROLLERWIDTH:Number = 130;
		
		private var _buttonShowDci:Dictionary = new Dictionary();
		private var _buttonEnableDic:Dictionary = new Dictionary();
		
		private var _childGridEntityName:String;
		private var _hasChildGrid:Boolean = false;
		
		private var _gridSelectedItem:Object;
		private var _allowMultipleSelection:Boolean = false;
		
		public var childZZGrid:ZZGrid;
		public var parentForm:ZZEditForm;
		
		public var changeList:ArrayCollection  = new ArrayCollection();
		
		public static var   DELETE:Number =  8;
		public static var   MODIFY:Number = 16;
		public static var	ADD:Number = 4;
		
		private var _btnList:ArrayCollection = new ArrayCollection();
		//constructor
		public function ZZGrid(url:String=null)
		{
			super();
			setStyle("horizontalAlign","center");
			setStyle("verticalAlign","middle");
			percentHeight =100;
			percentWidth =100;
			if(url!==null && url!==""){
				this._url = url;
				loadXmlGrid();	
			}
			_dataGrid = new DataGrid();
			createSearchForm();
		}
		/**
		 * 加载xml
		 * **/
		private function loadXmlGrid():void{
			LoadXmlUtil.loadXml(this._url,loadXmlResultHandler);
		}
		
		/***
		 * 重写 createChildren方法
		 * **/
		override protected function createChildren():void{
			super.createChildren();
			//若xmldata不为空的时候才创建
			if(this._xmlData.length!==0){
				percentWidth = 100;
				percentHeight = 100;
				initEvents();
				createCmp();	
			}
		}
		//create zzgird's  event
		private function initEvents():void{
			addEventListener("search",doSearchHandler);
			addEventListener("sendBindObject",sendBindObject);
			
		}
		
		//create dategrid's compoment
		private function createCmp():void{
			createSearchFields();
			createDataGrid();
			createButtons();
		}
		
		
		private function createSearchForm():void{
			_formBox = new VBox();
			_formBox.percentWidth = 100;
			_formBox.setStyle("horizontalAlign","center");
			_formBox.setStyle("verticalAlign","middle");
			//初始化hbox内盛装控件的flowbox
			_formFlowBox = new FlowBox();
			_formFlowBox.percentWidth = 100;
			_formFlowBox.height = FLOWBOXHEIGHT;
			_formFlowBox.autoLayout = true;
			_formFlowBox.setStyle("paddingLeft",15);
			_formBox.addChild(_formFlowBox);
			addChild(_formBox);
		}


	
		private function createDataGrid():void{
			//create datagrid
			
			_dataGrid.percentHeight = 98;
			_dataGrid.percentWidth =98;
			_dataGrid.setStyle("textAlign","center");
			_dataGrid.doubleClickEnabled = true;
			_dataGrid.allowMultipleSelection = _allowMultipleSelection;
			//create columns by xml data
			_columns = createColumns();
			_dataGrid.columns = _columns;
			//_dataGrid.dataProvider = dateGridList;
			//create datagrid's events
			initDataGridEvents();
			
			addChild(_dataGrid);
			
		}
		
		private function initDataGridEvents():void{
			_dataGrid.addEventListener(MouseEvent.CLICK,clickRowHandler);
			_dataGrid.addEventListener(MouseEvent.DOUBLE_CLICK,dbClickRowHandler);
		}
		
		
	
		//create buttons and button box
		private function createButtons():void{
			//create button box
			_btnBox = new HBox();
			_btnBox.percentWidth = 98;
			_btnBox.setStyle("horizontalAlign","right");
			_btnBox.setStyle("paddingBottom",5);
			//create add button
			_addBtn = new Button();
			_addBtn.label="新增";
			//create delete button
			_delBtn = new Button();
			_delBtn.label = "删除";
			_delBtn.visible = false;
			_buttonShowDci[_delBtn] = false;
			_delBtn.enabled = false;
			_buttonEnableDic[_delBtn] = false;
			//create update button
			_updateBtn = new Button();
			_updateBtn.label = "修改";
			_updateBtn.visible = false;
			_updateBtn.enabled = false;
			_buttonShowDci[_updateBtn] = false;
			_buttonEnableDic[_updateBtn] = false;
			//init buttons' events
			initButtonEvent();
			//add to containers
			_btnBox.addChild(_addBtn);
			_btnBox.addChild(_delBtn);
			_btnBox.addChild(_updateBtn);
			_btnList.addItem(_addBtn);
			_btnList.addItem(_delBtn);
			_btnList.addItem(_updateBtn);
			addChild(_btnBox);
			
			//
			if(_readOnly){
				changeButtonReadOnly();
			}
		}
		
		private function initButtonEvent():void{
			_addBtn.addEventListener(MouseEvent.CLICK,addButtonHandler);
			_delBtn.addEventListener(MouseEvent.CLICK,delButtonHandler);
			_updateBtn.addEventListener(MouseEvent.CLICK,updateButtonHandler);
		}
		
		
								//all of the events function//
		
		//--------------------------buttons event begin-------------------------------
			private function addButtonHandler(e:MouseEvent):void{				//
				_dataGrid.selectedIndex =-1;
				addObject.apply(_dataGrid,[ADD]);
				//dispatchEvent(new Event(Event.CHANGE));
			}
			private function delButtonHandler(e:MouseEvent):void{				//
				if(_dataGrid.selectedIndex!=-1){
					var obj:Object = _dataGrid.selectedItem;
					obj.rowStatus = DELETE;
					deleteObject.apply(_dataGrid,[obj]);
				}
					
			}
			private function updateButtonHandler(e:MouseEvent):void{			//
				dbClickRowHandler(null);
			}
		//---------------------------buttons event end--------------------------------
		
		
		
		//---------------------------datagrid's envet begin---------------------------
			private function clickRowHandler(e:MouseEvent):void{				//
				if(_readOnly){
					_updateBtn.enabled = true;
					return;
				}
				if(_dataGrid.selectedIndex!==-1){
					if(!_buttonShowDci[_delBtn]){
						_buttonShowDci[_updateBtn] = true;
						_delBtn.visible = true;
						_updateBtn.visible = true;
						_buttonShowDci[_delBtn] = true;
						
					}if(!_buttonEnableDic[_updateBtn]){
						_buttonEnableDic[_delBtn]= true;
						_buttonEnableDic[_updateBtn]= true;
						_updateBtn.enabled = true;
						_delBtn.enabled = true;
					}
				}
			}
			private function dbClickRowHandler(e:MouseEvent):void{				//
				if(_dataGrid.selectedIndex!==-1){
//					if(_allowMultipleSelection==false){
//						_gridSelectedItem = _dataGrid.selectedItem;
//					}else{
						//_gridSelectedItem = _dataGrid.selectedItems;
//					}
					_gridSelectedItem = _dataGrid.selectedItem
					sendBindObject.apply(_dataGrid,[_dataGrid.selectedItems]);
					
				}
				resetDataGird();
				
			}
			private function resetDataGird():void{
				_dataGrid.selectedIndex =-1;
				_buttonEnableDic[_updateBtn] = false;
				_buttonEnableDic[_delBtn] = false;
				_updateBtn.enabled = false;
				_delBtn.enabled = false;
			}
			
		//----------------------------datagrid's envet end-----------------------------
		
		
		
		//--------------------------search form event begin----------------------------
			private function typeEnterHandler(e:FlexEvent):void{			//
				dispatchEvent( new Event("search"));
				//TODO search data
			}
			
			private function restSearchFormHandler(e:MouseEvent):void{
				for(var i:int=0;i<_controlList.length;i++){
					var obj:Object = _controlList[i];
					if(obj is TextInput || obj is TextArea){
						obj.text = "";
					}else if(obj is DateField){
						DateField(obj).selectedDate = null;
						DateField(obj).text = "";
					}else if(obj is ComboBox){
						ComboBox(obj).selectedIndex = -1;
					}else if(obj is RadioButton){
						RadioButton(obj).selected = false;
					}
				}
				if(resetHanlder!=null){
					resetHanlder.apply(this);
				}
				
			}
		//--------------------------search form event end------------------------------
		
		
		
		//--------------------------xml result event end------------------------------
			private function loadXmlResultHandler(e:ResultEvent):void{			//
				var xmlList:XMLList = e.result.column as XMLList;
				var ay:Array = new Array();
				var gy:Array = new Array();
				for(var i:int=0;i<xmlList.length();i++){
					var p:String = xmlList[i].@parent;
					if(p!==null && p==="form"){
						ay.push(xmlList[i]);
					}else{
						gy.push(xmlList[i]);
					}
				}
				_formData = ay;
				xmlData = gy;
			}
		//--------------------------xml result event end------------------------------
//			private function doSearchHandler():void{
//				//TODO
//				dispatchEvent( new Event("search"));
//			}
		
		
		
		/***---------------------------build datagrid columns-----------------------------***/
			//create normal grid column
			private function createColumns():Array{
				var ay:Array = new Array();
				var len:int = _xmlData.length;
				for(var i:int=0;i<len;i++){
					var renderer:String =XML(_xmlData[i]).@itemRender;
					var c:DataGridColumn = new DataGridColumn();
					if(renderer==="" || renderer===null){
						c = createNormalColumn(XML(_xmlData[i]));
					}else if(renderer==="date"){
						c = createColumnWithDateRenderer(XML(_xmlData[i]));
					}
					else if(renderer=='entity'){
						c = createColumnWithEntityRenderer(XML(_xmlData[i]));
					}
//					if(XML(_xmlData[i]).@sortable!=null && XML(_xmlData[i]).@sortable!=''){
//						c.sortable = XML(_xmlData[i]).@sortable;
//					}
					
					ay.push(c);
				}
				return ay;
			}
			private function createNormalColumn(xml:XML):DataGridColumn{
				var header:String = xml.@header;
				var dateField:String = xml.@dateField;
				var c:DataGridColumn = new DataGridColumn();
				c.dataField = dateField;
				c.headerText = header;
				
				return c;
			}
			
			private function createColumnWithDateRenderer(xml:XML):DataGridColumn{
				var header:String = xml.@header;
				var dateField:String = xml.@dateField;
				var c:DataGridColumn = new DataGridColumn();
				c.dataField = dateField;
				c.headerText = header;
				c.itemRenderer = new ClassFactory(DateRenderer);
				return c;
			}
			private function createColumnWithEntityRenderer(xml:XML):DataGridColumn{
				var p:String = xml.@property;
				var header:String = xml.@header;
				var dateField:String = xml.@dateField+"."+xml.@property;
				var c:DataGridColumn = new DataGridColumn();
				c.dataField = dateField;
				c.headerText = header;
				c.itemRenderer = new ClassFactory(EntityRenderer);
				//if(xml.sortable==false){
				c.sortable = false;
				//}
				return c;
				
			}
		/***--------------------------------------------------------***/
		/***---------------------------build search form's items-----------------------------***/
			//create search from items		
			private function createSearchFields():void{
				var len:int = _formData.length;
				for(var i:int=0;i<len;i++){
					var control:UIComponent;
					var type:String = XML(_formData[i]).@type;
					var fitem:FormItem = new FormItem();
					fitem.setStyle("labelWidth",LABWIDTH);
					fitem.width = LABWIDTH + CONTROLLERWIDTH + 15;
					fitem.label = _formData[i].@label;
					//根据type创建表单组件
					if(type=="textInput"){
						control = createTextInput(XML(_formData[i]));
						if(i===len-1){
							control.addEventListener("enter",typeEnterHandler);
						}
					}else if(type=="comboBox"){
						control = createComboBox(XML(_formData[i]));
					}else if(type=="dateField"){
						control = createDateField(XML(_formData[i]));
					}else if(type=="numberField"){
						control = createNumberField(XML(_formData[i]));
						if(i===len-1){
							control.addEventListener("enter",typeEnterHandler);
						}
					}
					else if(type=="checkBox"){
						control = createCheckBox(XML(_formData[i]));
					}else if(type=="radio"){//radio做特殊处理
						var xml:XML = XML(_formData[i]);
						var gName:String = XML(_formData[i]).@id;
						//------------------radio-------------//
							var la:RadioHBox = new RadioHBox();
							la.width =  LABWIDTH + CONTROLLERWIDTH + 15;
							var rbox:HBox = new HBox();
							rbox.percentWidth = 80;
							rbox.setStyle("paddingLeft",2);
							var label:Label = new Label();
							label.width = LABWIDTH;
							label.text = xml.@grouName;	
							la.addChild(label);
						//------------------radio-------------//

						var children:XMLList = XML(_formData[i]).column;
						for(var k:int=1;k<children.length()+1;k++){
							control = createRadio(children[k-1],gName);
							
							rbox.addChild(control);
							_controlList.addItem(control);
						}
						la.addChild(rbox);
						//_controlDic[RadioButton(control).groupName] = control;
						_formFlowBox.addChild(la);
					}
					
					//装入flowbox容器内 radio 因为布局关系
					if(control != null && !(control is RadioButton)){
						fitem.addChild(control);
						_formFlowBox.addChild(fitem);
						
					}
					//因为radio是一组指向一个属性，所以要分别处理
					if(control != null && !(control is RadioButton)){
						//装入dic内
						_controlDic[control.id] = control;
						//装入ay内
						_controlList.addItem(control);
					}
					if(i>=3){
						_formFlowBox.height = FLOWBOXHEIGHT*2.2;
					}
					
				}
				//create search box and button
				if(len!=0){
					_searchBBox = new HBox();
					_searchBBox.percentWidth = 85;
					_searchBBox.height = 28;
					_searchBBox.setStyle("horizontalAlign","right");
					var sp:Spacer = new Spacer();
					sp.percentWidth = 60;
					_searchButton = new Button();
					_searchButton.label = "查询";
					_resetButtion = new Button();
					_resetButtion.label = "重置";
					_searchButton.addEventListener(MouseEvent.CLICK,doSearchHandler);
					_resetButtion.addEventListener(MouseEvent.CLICK,restSearchFormHandler);
					_searchBBox.addChild(sp);
					_searchBBox.addChild(_resetButtion);
					_searchBBox.addChild(_searchButton);
					_formBox.addChild(_searchBBox);
				}
				
				
			}
			//创建TextInput控件
			private function createTextInput(xml:XML):TextInput{
				var c:TextInput = new TextInput();
				c.id = xml.@id;
				c.width = CONTROLLERWIDTH;
				return c;
			}
			//创建DateField控件
			private function createDateField(xml:XML):DateField{
				var c:DateField = new DateField();
				c.id = xml.@id;
				c.width = CONTROLLERWIDTH;
				c.formatString="YYYY-MM-DD";
				return c;
			}
			//创建numberFiled控件
			private function createNumberField(xml:XML):NumberField{
				
				var nf:NumberField = new NumberField();
				nf.id = xml.@id;
				nf.width = CONTROLLERWIDTH;
				if(xml.@numberOnly==true){
					nf.type = "int";
				}
				return nf;
			}
			//创建checkbox控件
			private function createCheckBox(xml:XML):CheckBox{
				var cb:CheckBox = new CheckBox();
				cb.label = xml.@label;
				cb.width = CONTROLLERWIDTH;
				
				return cb;
			}
			//创建radio控件组
			private function createRadio(xml:XML,groupName:String):RadioButton{
				var radio:RadioButton = new RadioButton();
				radio.label = xml.@name;
				radio.groupName = groupName;
				radio.value = xml.@value;
				radio.width = (CONTROLLERWIDTH)/3;
				return radio;
			}
				//创建comboBox控件
			private function createComboBox(xml:XML):ZZComBox{
				var zcmb:ZZComBox = new ZZComBox();
				zcmb.id = xml.@id;
				zcmb.width = CONTROLLERWIDTH;
				var pro:String = xml.@dataProvider;
				if(pro != null && pro ){
					//从appmodel中取出对应comboBox的dataProvider
					zcmb.queryObject = xml.@entity;
					zcmb.dataProviderName = pro;
				}else if(xml.@userLabel==true){
					zcmb.useLabel = true;
					var labList:XMLList = xml.column;
					var ary:ArrayCollection = new ArrayCollection();
					for(var i:int=0;i<labList.length();i++){
						var obj:Object = new Object();
						obj['name'] = labList[i].@name[0];
						obj['value'] = labList[i].@value[0];
						ary.addItem(obj);
					}
					zcmb.dataProvider = ary;
				}
				
				zcmb.labelField = xml.@fieldName;
				zcmb.prompt = " ";
				zcmb.selectedIndex = -1;
				//将表单内的comboBox放入list中
				this._comboxList.addItem(zcmb);
				return zcmb; 
			}
		/***--------------------------------------------------------***/
		
		/***-----------------create query info--------------------------------------***/
			//通过外部调用该方法获取search from 中的queryInfo
			public function getQueryInfo(entityName:String):QueryInfoVO{
				var q:QueryInfoVO = new QueryInfoVO();
				q.entityAlias = null;
				q.listType = QueryInfoVO.LISTTYPE_LIST;
				q.conjunctionType = QueryInfoVO.CONJUNCTIONTYPE_AND;
				q.queryObjectName = entityName;
				q.fields = createQueryFields();
				return q;
			}
			private function createQueryFields():Array{
				var fieldList:Array = new Array();
				var len:int = _controlList.length;
				for(var i:int=0;i<len;i++){
					var c:Object = 	_controlList[i];
					var field:FieldVO = new FieldVO();
					field.condition = QueryInfoVO.CONDITION_LIKE_END_IC;
					if(c is TextInput && !(c is NumberField)){
						field.fieldName = c.id;
						field.fieldValue  = c.text;
					}else if(c is ZZComBox){//comboBox
						var cb:ZZComBox = c as ZZComBox;
						if(cb.selectedIndex!=-1){
							field.fieldName = cb.labelField;
							if(cb.useLabel){//不用实体关联查询
								field.fieldValue = cb.text;
							}else{//使用实体关联查询
								field.fromAssociateObject = cb.id;
								field.fieldValueString = cb.text;
							}
							
						}
					}else if(c is DateField){
						field.fieldName = DateField(c).id;
						field.fieldValue = DateField(c).selectedDate;
					}else if(c is CheckBox){
						//TODO
					}else if(c is RadioButton){
						var r:RadioButton = c as RadioButton;
						field.fieldName = r.groupName;
						if(r.selected){
							field.fieldValue = r.value.toString();
						}
					}else if(c is NumberField){
						field.fieldName = NumberField(c).id;
						if(NumberField(c).text!='0'){
							field.fieldValue = NumberField(c).text;
						}
						
					}
					
					if(field.fieldValue!=null && field.fieldValue!=""){
						fieldList.push(field);
					}
					if(field.fieldValueString!=null && field.fieldValueString!=''){
						fieldList.push(field);
					}
					
				}
				return fieldList;
			}
		private	function changeButtonReadOnly():void{
			var len:Number = _btnList.length;
			for(var i:Number=0;i<len;i++){
				var b:Button = _btnList[i] as Button;
				if(b.label=='修改'){
					b.label = '查看';
					b.visible = true;
				}else{
					b.visible = false;
				}
			}
		}
		
		/***--------------------------------------------------------***/
		
		public function get readOnly():Boolean{
			return this._readOnly;
		}
		public function  set readOnly(value:Boolean):void{
			this._readOnly = value;
			changeButtonReadOnly();
		}
		
		public function set controlList(value:ArrayCollection):void{
			this._controlList = value;
		}
		public function get controlList():ArrayCollection{
			return this._controlList;
		}
		public function set dataGrid(value:DataGrid):void{
			this._dataGrid = value;
		}
		public function get dataGrid():DataGrid{
			return this._dataGrid;
		}
		
		public function set gridSelectedItem(value:Object):void{
			this._gridSelectedItem = value;
		}
		public function get gridSelectedItem():Object{
			return this._gridSelectedItem;
		}
		
		public function set hasChildGrid(value:Boolean):void{
			this._hasChildGrid = value;
		}
		public function get hasChildGrid():Boolean{
			return this._hasChildGrid;
		}
		
		
		
		public function set childGridEntityName(value:String):void{
			this._childGridEntityName = value;
		}
		public function get childGridEntityName():String{
			return this._childGridEntityName;
		}
		
		public function set columns(value:Array):void{
			this._columns = value
		}
		public function get columns():Array{
			return this._columns;
		}
		
		
		public function set comboxList(value:ArrayCollection):void{
			this._comboxList = value
		}
		public function get comboxList():ArrayCollection{
			return this._comboxList;
		}
		
		
		public function set xmlData(value:Array):void{
			this._xmlData = value;
			createChildren();
		}
		public function get xmlData():Array{
			return this._xmlData;
		}
		
		[Bindable]
		public function get comboBoxDataDic():Dictionary{
			return _comboBoxDataDic;
		}
		public function set comboBoxDataDic(value:Dictionary):void{
			_comboBoxDataDic = value;
			resetComboxData();
		}
		
		public function bindComboBoxData(name:String,aryy:ArrayCollection):void{
			var len:Number = _comboxList.length;
			for(var i:Number =0;i<len;i++){
				var cmb:ZZComBox = _comboxList[i] as ZZComBox;
				var pro:String = cmb.dataProviderName;
				if(pro==name){
					cmb.dataProvider = aryy;
					_comboBoxDataDic[name] = aryy;
				}				
			}
		}
		
		
		private function resetComboxData(value:Dictionary=null):void{
			if(value!=null){
				_comboBoxDataDic = value;
			}
			var len:Number = _comboxList.length;
			for(var i:Number =0;i<len;i++){
				var cmb:ZZComBox = _comboxList[i] as ZZComBox;
				var pro:String = cmb.dataProviderName;

				if(pro!=null && pro!=''){
					cmb.dataProvider = _comboBoxDataDic[pro] as ArrayCollection;
				}
				
				
			}
		}
		
	}
}